import pyflag.FlagFramework as FlagFramework
import pyflag.conf
config=pyflag.conf.ConfObject()
import pyflag.FileSystem as FileSystem
import pyflag.Reports as Reports
import pyflag.DB as DB
from pyflag.Scanner import *
import pyflag.Scanner as Scanner
from pyflag.ColumnTypes import StringType, InodeIDType, ColumnType, FilenameType, IntegerType, TimestampType, LongStringType, BinaryType
import pyflag.Reports as Reports
import os.path
import sqlite3
import re

class GaduGaduArchivesFoundCaseTable(FlagFramework.CaseTable):
    """ Found Gadu Gadu archives table class. """
    # primary= "inode_id"
    name = 'gg_archives'
    columns = [
      [InodeIDType, {}],
      [StringType, {"name":"Path", "column":"path"}],
      [IntegerType, {"name":"#GG", "column":"interlocutor"}],
      [BinaryType, {"name":"Incoming", "column":"incoming"}],
      [LongStringType, {"name":"Chat", "column":"chat"}],
      [TimestampType, {"name":"timestamp", "column":"timestamp"}],
    ]

class GGFinder(Reports.report):
    """ A report class for finding GG archive files """
    name = "Show found GG Archives"
    family = "Log Finder"
    description="The report returns a table of known Gadu Gadu archive files."

    def form(self,query,result):
        result.case_selector()
        
    def display(self,query,result):
        dbh=self.DBO(query['case'])
        try:
            result.table(
                elements = [ 
                             FilenameType(case=query['case']),
                             IntegerType('#GG', 'interlocutor'),
                             IntegerType('Incoming', 'incoming'),
                             TimestampType(name='Timestamp', column='timestamp'),
                             LongStringType(name='Chat', column='chat'),
                             ],
                table = 'gg_archives',
                case = query['case']
                )
        except DB.DBError,e:
            result.para("Error reading the Type table.")
            result.para("Error reported was:")
            result.text(e,style="red")

def is_gg_archive(filename):
    print "Processing %s" % (filename)
    conn = sqlite3.connect(os.path.abspath(filename))
    c = conn.cursor()
    try:
        query = c.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND tbl_name IN ('interlocutors', 'chats', 'communication_items')")
    except sqlite3.Error:
        return False
    row = query.fetchone()
    table_count = row[0]
    return table_count == 3

def iterate_gg_chats(filename):
    conn = sqlite3.connect(os.path.abspath(filename))
    query = """SELECT i.identification, NOT ci.is_sent_by_user, ci.content, ci.start_date
               FROM chats AS c 
               INNER JOIN interlocutors AS i ON i.interlocutor_id = c.interlocutor_id
               INNER JOIN communication_items AS ci ON ci.chat_id = c.chat_id
            """
    cursor = conn.cursor().execute(query)
    row = cursor.fetchone()
    while row:
        yield row
        row = cursor.fetchone()

class GGArchiveScan(GenScanFactory):
    """ Scan filesystem for GG Archives """
    default = True
    depends = ['TypeScan']
    group = "FileScanners"
    order=400

    class Scan(BaseScanner):

        def process(self, data,metadata=None):
            dbh=DB.DBO(self.case)


        def finish(self):
            dbh=DB.DBO(self.case)

            template = "INSERT INTO gg_archives(inode_id, path, interlocutor, incoming, chat, timestamp) values (%s, '%s', %s, %s, '%s', '%s')"
            # FIXME -- my low knowledge on python didn't let me import this class so I check it by "string"
            if self.fd.__class__.__name__ == "MountedFS_file" and is_gg_archive(self.fd.fd.name):
                for interlocutor, incoming, chat, timestamp in iterate_gg_chats(self.fd.fd.name):
                    chat_stripped = re.sub(r'<[^>]*?>', '', chat)
                    sql = template % (self.inode_id, self.fd.fd.name, interlocutor, incoming, chat_stripped, timestamp)
                    dbh.execute(sql)
